# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import json
import re
import os
import redis
import datetime
import shutil
from django.shortcuts import render,HttpResponse
from app_sys import models
from app_cmdb.models import HostInfo,HostGroup,LoginUser
from django.contrib.auth.models import User
from app_rbac.models import UserInfo,Role
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from app_auth.views import Perms_required
from app_sys import salt_script,get_dir,salt_cp_file
from mtrops.settings import BASE_DIR,REDIS_HOST,HOST,SALT_HOST
from django.views.generic import View





@login_required
@Perms_required
def Depend(request):
    title = '环境部署'

    hostgroup_obj = HostGroup.objects.all()
    tree_info = []
    n=1
    for i in hostgroup_obj:
        hostgroup_id = i.id
        hostgroup_name = i.group_name
        hostinfo_obj = HostInfo.objects.filter(host_group_id=hostgroup_id)
        if n == 1:
            tree_info.append({"id": hostgroup_id, "pId": 0, "name": hostgroup_name, "open": "true"})
        else:
            tree_info.append({"id": hostgroup_id, "pId": 0, "name": hostgroup_name, "open": "false"})
        n+=1
        for j in hostinfo_obj:
            host_id = j.id
            host_ip = j.IP
            id = hostgroup_id * 10 + host_id
            if j.os_type == "Linux":
                tree_info.append({"id": id, "pId": hostgroup_id, "name": host_ip})
            else:
                pass
    data = json.dumps(tree_info, ensure_ascii=False)

    depend_obj = models.Server_Install.objects.all()
    depend_list = []
    for depend in depend_obj:
        depend_id = depend.id
        depend_name = depend.depend_name
        depend_version = depend.depend_version

        install_script = depend.install_script
        depend_list.append({'depend_id':depend_id,'depend_name':depend_name,'depend_version':depend_version,'install_script':install_script})
    return render(request, "sys_server.html", locals())





@csrf_exempt
@login_required
@Perms_required
def AddDepend(request):
    if request.method == 'POST':
        depend_name = request.POST.get('depend_name')
        depend_version = request.POST.get('depend_version')

        install_script = request.POST.get('install_script')

        try:
            depend_obj = models.Server_Install(depend_name=depend_name, depend_version=depend_version,install_script=install_script)
            depend_obj.save()
            return HttpResponse('添加成功')
        except:
            return HttpResponse('添加失败')
    else:
        return HttpResponse("未知请求")



@csrf_exempt
@login_required
@Perms_required
def EditDepend(request):
    if request.method == "POST":
        depend_id = request.POST.get("depend_id")
        depend_name = request.POST.get('depend_name')
        depend_version = request.POST.get('depend_version')


        install_script = request.POST.get('install_script')
        action = request.POST.get("action", None)
        if action:
            depend_obj = models.Server_Install.objects.get(id=depend_id)
            depend_obj.depend_name = depend_name
            depend_obj.depend_version = depend_version


            depend_obj.install_script = install_script
            depend_obj.save()
            return HttpResponse("修改成功")
        else:
            depend_info = models.Server_Install.objects.get(id=depend_id)
            info_json = {'depend_id':depend_info.id,'depend_name':depend_info.depend_name,'depend_version':depend_info.depend_version,'install_script':depend_info.install_script}
            info_json = json.dumps(info_json)
            return HttpResponse(info_json)
    else:
        return HttpResponse("未知请求")



@csrf_exempt
@login_required
@Perms_required
def DelDepend(request):
    if request.method == "POST":
        depend_id = request.POST.get("depend_id")
        models.Server_Install.objects.get(id=depend_id).delete()
        return HttpResponse("已删除")


@csrf_exempt
@login_required
@Perms_required
def Install(request):

    if request.method == "POST":
        depend_id = request.POST.get("depend_id")
        ip_json = request.POST.get("node_id_json")

        ip_list = []
        for i in json.loads(ip_json):
            if re.search("\d+.\d+.\d+.\d",i):
                ip_list.append(i)
        depend_obj = models.Server_Install.objects.get(id=depend_id)
        install_script = depend_obj.install_script
        depend_name = depend_obj.depend_name


        script_name = "install_%s" % depend_name

        script_file = os.path.join(BASE_DIR, 'static', 'scripts',script_name)

        f = open(script_file,'wb')

        f.write(install_script)

        f.close()

        script_file = "salt://%s" % script_file

        runas = json.loads(request.session['webssh_info'])['username']

        result = salt_script.script(ip_list,script_file,runas)

        return HttpResponse(result)




@csrf_exempt
@login_required
@Perms_required
def FileMG(request,ip=HOST,Dir=None):


    title = "文件管理"

    r = redis.Redis(host=REDIS_HOST, port=6379, db=0)


    hostgroup_obj = HostGroup.objects.all()
    tree_info = []

    for i in hostgroup_obj:
        hostgroup_id = i.id
        hostgroup_name = i.group_name
        hostinfo_obj = HostInfo.objects.filter(host_group_id=hostgroup_id)
        tree_info.append({"id":hostgroup_id, "pId":0, "name":hostgroup_name, "open":"true"})

        for j in hostinfo_obj:
            host_id = j.id
            host_ip =  j.IP
            id = hostgroup_id*10+host_id

            if j.os_type=="Windows":
                pass
            else:
                tree_info.append({"id": id, "pId": hostgroup_id, "name": host_ip})

    data =  json.dumps(tree_info,ensure_ascii=False)


    if Dir:

        if r.get('cur_dir') !='/':
            cd_dir = r.get('cur_dir')+"/"+Dir
        else:
            cd_dir = r.get('cur_dir') + Dir
    else:
        cd_dir = '/'

    runas = json.loads(request.session['webssh_info'])['username']

    a = get_dir.main(ip,cd_dir,runas)


    result = a[ip]

    if re.search("Permission denied",result):
        msg = "权限不足，无法访问！"
        file_list=json.loads(r.get('file_list'))
        dir_list = json.loads(r.get('dir_list'))
        cur_dir = r.get('cur_dir')

    else:
        msg = ""

        cur_dir =  result.split("\n")[0]

        r.set('cur_dir', cur_dir)

        r.set('cur_host', ip)

        file_list = []

        dir_list = []

        for i in result.split("\n")[1:]:
            F = i.split()
            if re.match(r"-", F[0]):
                file_list.append(F[1])

            else:
                dir_list.append(F[1])

        r.set('file_list', json.dumps(file_list))

        r.set('dir_list', json.dumps(dir_list))

    return render(request,"sys_file.html",locals())


@csrf_exempt
@login_required
@Perms_required
def ch_dir(request):
    if request.method == "POST":

        cd_dir = request.POST.get("cd_dir")


        ip = request.POST.get("ip")



        r = redis.Redis(host=REDIS_HOST, port=6379, db=0)

        runas = json.loads(request.session['webssh_info'])['username']


        a = get_dir.main(ip,cd_dir,runas)

        result = a[ip]

        if re.search("Permission denied", result):
            msg = "权限不足，无法访问！"
            file_list = json.loads(r.get('file_list'))
            dir_list = json.loads(r.get('dir_list'))
            cur_dir = r.get('cur_dir')

        else:
            msg = ""

            cur_dir = result.split("\n")[0]

            r.set('cur_dir', cur_dir)

            r.set('cur_host', ip)

            file_list = []

            dir_list = []

            r.set('file_list', file_list)
            r.set('dir_list', dir_list)

            for i in result.split("\n")[1:]:
                F = i.split()
                if re.match(r"-", F[0]):
                    file_list.append(F[1])

                else:
                    dir_list.append(F[1])

            r.set('file_list', json.dumps(file_list))

            r.set('dir_list', json.dumps(dir_list))


        return render(request, "sys_file_list.html", locals())
    else:
        return HttpResponse("未知请求")



#上传文件
@csrf_exempt
@login_required
@Perms_required
def Upfile(request):
    if request.method == "POST":

        r = redis.Redis(host=REDIS_HOST, port=6379, db=0)

        path = r.get('cur_dir')

        upfile = request.FILES.get("upfile")

        ip = r.get('cur_host')

        up_file_path = os.path.join(BASE_DIR,'static', 'upload', ip)

        if os.path.exists(up_file_path):
            pass
        else:
            os.makedirs(up_file_path)

        file_path = os.path.join(up_file_path, upfile.name)


        src = "salt://"+file_path

        dest = path.rstrip("/")+"/"+upfile.name


        if os.path.exists(file_path):
            date_str = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            os.rename(file_path, file_path+"_"+date_str)
        else:
            pass

        f = open(file_path,'wb')

        for chunk in upfile.chunks():
            f.write(chunk)
        f.close()


        result = salt_cp_file.upfile(ip, src, dest)

        if result[ip]:
            msg = "上传成功"
        else:
            msg = "上传失败"
        return HttpResponse(msg)
    else:
        return HttpResponse("未知请求")


# 下载文件
@csrf_exempt
@login_required
@Perms_required
def Downfile(request):
    if request.method == "POST":
        r = redis.Redis(host=REDIS_HOST, port=6379, db=0)

        filename = request.POST.get("filename")

        if r.get('cur_dir') != '/':
            path = r.get('cur_dir')+'/'+filename
        else:
            path = r.get('cur_dir') + filename

        ip = r.get('cur_host')


        result = salt_cp_file.downfile(ip, path)

        if result[ip]:
            salt_file_path = "/var/cache/salt/master/minions/%s/files" % ip

            downfile_path = os.path.join(BASE_DIR, 'static', 'download', ip)

            if os.path.exists(downfile_path):
                pass
            else:
                os.makedirs(downfile_path)


            salt_file = salt_file_path + path

            save_file = downfile_path + "/" + filename


            if os.path.exists(save_file):
                date_str = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
                os.rename(save_file, save_file + "_" + date_str)
            else:
                pass

            shutil.move(salt_file,save_file)

            msg = "http://%s:8080/static/download/%s/%s" % (SALT_HOST,ip, filename)

        else:
            msg = "下载失败，请检查文件是否存在"

        return HttpResponse(msg)
    else:
        return HttpResponse("未知请求")



@csrf_exempt
@login_required
@Perms_required
def Removefile(request):
    '''文件管理-删除文件'''
    if request.method == "POST":
        r = redis.Redis(host=REDIS_HOST, port=6379, db=0)

        filename = request.POST.get("filename")

        if r.get('cur_dir') != '/':
            path = r.get('cur_dir')+'/'+filename
        else:
            path = r.get('cur_dir') + filename

        ip = r.get('cur_host')

        result = salt_cp_file.removefile(ip, path)

        return HttpResponse(result)
    else:
        return HttpResponse("未知请求")




@csrf_exempt
def batch(request):
    """批量管理"""
    title='批量管理'
    hostgroup_obj = HostGroup.objects.all()
    tree_info = []

    for i in hostgroup_obj:
        hostgroup_id = i.id
        hostgroup_name = i.group_name
        hostinfo_obj = HostInfo.objects.filter(host_group_id=hostgroup_id)

        tree_info.append({"id": hostgroup_id, "pId": 0, "name": hostgroup_name, "open": "flase"})

        for j in hostinfo_obj:
            host_id = j.id
            host_ip = j.IP
            id = hostgroup_id * 10 + host_id

            if j.os_type == "Linux":
                tree_info.append({"id": id, "pId": hostgroup_id, "name": host_ip})
            else:
                pass

    data = json.dumps(tree_info, ensure_ascii=False)

    remote_user_list = []

    user_id = User.objects.get(username=request.session['username']).id

    user_obj = UserInfo.objects.get(user_id=user_id)

    role_id = user_obj.role_id

    role_obj = Role.objects.get(id=role_id)

    user_role = role_obj.role_title

    if user_role == "administrator":
        remote_user_obj = LoginUser.objects.all()
    else:
        user_info_id = user_obj.id

        remote_user_obj = LoginUser.objects.filter(people_id=user_info_id)

    for i in  remote_user_obj:
        remote_user_list.append(i.login_user)

    return render(request,'sys_batch.html',locals())



@csrf_exempt
def batch_cmd_run(request):
    """批量执行命令"""
    if request.method == "POST":

        cmd= request.POST.get('cmd')

        ip_list = json.loads(request.POST.get("ip_list"))

        runas = json.loads(request.session['webssh_info'])['username']

        data=salt_script.cmdrun(ip_list,cmd,runas)

        data_txt=''
        for ip in  ip_list:
            head_txt='=================== %s ===================\n' % ip
            result_info = "%sCommand：%s\nOutput：\n%s\n\r" % (head_txt,cmd,data[ip])
            data_txt+=result_info

        return HttpResponse(data_txt)



@csrf_exempt
def batch_upload_file(request):
    """批量执行命令"""
    if request.method == "POST":
        upload_path = request.POST.get('upload_path')

        upload_file = request.FILES.get("upfile")

        ip_list = json.loads(request.POST.get("ip_list"))

        up_file_path = os.path.join(BASE_DIR, 'static', 'upload')

        if os.path.exists(up_file_path):
            pass
        else:
            os.makedirs(up_file_path)

        file_path = os.path.join(up_file_path, upload_file.name)

        src = "salt://" + file_path

        dest = upload_path.rstrip("/") + "/" + upload_file.name

        if os.path.exists(file_path):
            date_str = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            os.rename(file_path, file_path + "_" + date_str)
        else:
            pass

        f = open(file_path, 'wb')

        for chunk in upload_file.chunks():
            f.write(chunk)
        f.close()

        runas = json.loads(request.session['webssh_info'])['username']

        data = salt_script.upload_file(ip_list, src, dest,runas)

        data_txt=''
        for ip in  ip_list:
            head_txt='=================== %s ===================\n' % ip
            result_info = "%sOutput：\n%s\n\r" % (head_txt,data[ip])
            data_txt+=result_info

        return HttpResponse(data_txt)



@csrf_exempt
def batch_script(request):
    """批量执行命令"""
    if request.method == "POST":

        up_script = request.FILES.get("script_file")

        ip_list = json.loads(request.POST.get("ip_list"))

        script_dir = os.path.join(BASE_DIR, 'static', 'scripts')

        if os.path.exists(script_dir):
            pass
        else:
            os.makedirs(script_dir)

        script_file = os.path.join(script_dir, up_script.name)

        if os.path.exists(script_file):
            date_str = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            os.rename(script_file, script_file + "_" + date_str)
        else:
            pass

        f = open(script_file, 'wb')

        for chunk in up_script.chunks():
            f.write(chunk)
        f.close()

        script_src = "salt://" + script_file

        runas = json.loads(request.session['webssh_info'])['username']

        data = salt_script.script(ip_list,script_src,runas)

        data_txt=''
        for ip in  ip_list:
            head_txt='=================== %s ===================\n' % ip
            result_info = "%sOutput：\n%s\n\r" % (head_txt,data[ip]['stdout'])
            data_txt+=result_info

        return HttpResponse(data_txt)


class CronView(View):
    """
    计划任务管理
    """
    @csrf_exempt
    def get(self,request):

        ip_list = json.loads(request.GET.get('ip_list'))

        remote_user = request.GET.get('remote_user')

        cmd='crontab -u %s -l' % remote_user

        data = salt_script.cmdrun(ip_list, cmd, 'root')

        data_info = []

        for ip in data.keys():

            data_list = data[ip].split('\n')
            cron_list = []
            if re.match('no', data_list[0]) or re.match('crontab', data_list[0]):
                cron_list = []
            else:
                for i in data_list:
                    A = i.split()
                    if A:
                        B = A[0:5]
                        C = A[5:]
                        cmd = " ".join(C)
                        B.append(cmd)
                        cron_list.append({'m':B[0],'h':B[1],'d':B[2],'M':B[3],'w':B[4],'cmd':B[5],'org_cmd':i})

            data_info.append({"IP": ip, "cron": cron_list})

        return render(request,"sys_cron_table.html",locals())
    
    def post(self,request):
        ip_list = json.loads(request.POST.get('ip_list'))

        remote_user = request.POST.get('remote_user')

        Minute = request.POST.get('Minute')

        Hour = request.POST.get('Hour')

        Day = request.POST.get('Day')

        Month = request.POST.get('Month')

        Week = request.POST.get('Week')

        cron_cmd = request.POST.get('cron_cmd')

        cron_cmd = re.sub(r"\"","\'",cron_cmd)

        if Minute=='':
            Minute ='*'
        if Hour=='':
            Hour = '*'
        if Day == '':
            Day = '*'
        if Month == '':
            Month = '*'
        if Week == '':
            Week ='*'


        cmd= 'echo "%s %s %s %s %s %s" >> /var/spool/cron/%s' % (Minute,Hour,Day,Month,Week,cron_cmd,remote_user)

        data = salt_script.cmdrun(ip_list, cmd, 'root')

        data_txt = ''

        for ip in ip_list:
            head_txt = '=================== %s ===================\n' % ip
            result_info = "%sOutput：\n%s\n\r" % (head_txt,data[ip])
            data_txt += result_info


        return HttpResponse(data_txt)

    def put(self,request):
        del_info = eval(request.body.decode())

        ip = del_info['ip']

        ip_list = [ip]

        remote_user = del_info['remote_user']

        org_cmd = del_info['org_cmd']

        action = del_info['action']

        b = re.sub("\\*", "\*", org_cmd)

        c = re.sub("\/", "\/", b)

        d = re.sub('\"', '\\\"', c)

        d = re.sub("&", "\&", d)


        if action=='Del':
            cmd = '''sed -i "/%s/d"  /var/spool/cron/%s''' % (d,remote_user)
        elif action =="up":
            e = re.sub("^#","",d)
            cmd = '''sed -i "s/%s/%s/"  /var/spool/cron/%s''' % (d,e,remote_user)
        elif action =="ban":
            cmd = '''sed -i "s/%s/#%s/"  /var/spool/cron/%s''' % (d, d, remote_user)
        elif action =="edit":


            Minute = del_info['Minute']

            Hour = del_info['Hour']

            Day = del_info['Day']

            Month = del_info['Month']

            Week = del_info['Week']

            cron_cmd = del_info['cron_cmd']

            cron_new = """%s %s %s %s %s %s""" % (Minute,Hour,Day,Month,Week,cron_cmd)

            A = re.sub("\\*", "\*", cron_new)

            B = re.sub("\/", "\/", A)

            C = re.sub('\"', '\\\"', B)

            D = re.sub("&", "\&", C)

            cmd = '''sed -i "s/%s/%s/"  /var/spool/cron/%s''' % (d, D, remote_user)


        f_sed = os.path.join(BASE_DIR,'static','scripts','sed.sh')
        f=open(f_sed,'w')
        f.write(cmd)
        f.close()


        data = salt_script.script(ip_list, "salt://"+f_sed, 'root')

        result = data[ip]

        msg = "执行错误：%s\n\r执行结果：%s" % (result['stderr'],result['stdout'])

        return HttpResponse(msg)